using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

// 英雄数据模型
public class HeroModel : Model
{
    private int _heroId;
    private string _heroName = "";
    private int _level = 1;
    private int _star = 1;
    private float _attack = 100f;
    private float _defense = 50f;
    private float _health = 1000f;
    private bool _isUnlocked = false;
    
    // 英雄ID
    public int HeroId
    {
        get => _heroId;
        set => SetProperty(ref _heroId, value, nameof(HeroId));
    }
    
    // 英雄名称
    public string HeroName
    {
        get => _heroName;
        set => SetProperty(ref _heroName, value, nameof(HeroName));
    }
    
    // 英雄等级
    public int Level
    {
        get => _level;
        set => SetProperty(ref _level, value, nameof(Level));
    }
    
    // 英雄星级
    public int Star
    {
        get => _star;
        set => SetProperty(ref _star, value, nameof(Star));
    }
    
    // 攻击力
    public float Attack
    {
        get => _attack;
        set => SetProperty(ref _attack, value, nameof(Attack));
    }
    
    // 防御力
    public float Defense
    {
        get => _defense;
        set => SetProperty(ref _defense, value, nameof(Defense));
    }
    
    // 生命值
    public float Health
    {
        get => _health;
        set => SetProperty(ref _health, value, nameof(Health));
    }
    
    // 是否解锁
    public bool IsUnlocked
    {
        get => _isUnlocked;
        set => SetProperty(ref _isUnlocked, value, nameof(IsUnlocked));
    }
    
    // 战斗力计算
    public float CombatPower => Attack + Defense + Health * 0.1f;
    
    // 构造函数
    public HeroModel(int heroId, string heroName)
    {
        _heroId = heroId;
        _heroName = heroName;
    }
    
    // 升级英雄
    public void LevelUp()
    {
        Level++;
        Attack += 10f;
        Defense += 5f;
        Health += 100f;
        Debug.Log($"英雄 {HeroName} 升级到 {Level} 级！");
    }
    
    // 升星
    public void StarUp()
    {
        if (Star < 5)
        {
            Star++;
            Attack += 50f;
            Defense += 25f;
            Health += 500f;
            Debug.Log($"英雄 {HeroName} 升星到 {Star} 星！");
        }
    }
    
    // 解锁英雄
    public void Unlock()
    {
        IsUnlocked = true;
        Debug.Log($"英雄 {HeroName} 已解锁！");
    }
}

// 英雄列表变化事件参数
public struct HeroListChangedEventArgs
{
    public enum ChangeType
    {
        Added,      // 添加英雄
        Removed,    // 删除英雄
        Updated     // 更新英雄
    }
    
    public ChangeType Type { get; private set; }
    public HeroModel Hero { get; private set; }
    public int Index { get; private set; }
    
    public HeroListChangedEventArgs(ChangeType type, HeroModel hero, int index = -1)
    {
        Type = type;
        Hero = hero;
        Index = index;
    }
}

// 英雄列表管理模型
public class HeroListModel : Model
{
    private List<HeroModel> _heroes = new List<HeroModel>();
    private Dictionary<int, HeroModel> _heroDict = new Dictionary<int, HeroModel>();
    
    // 英雄列表变化事件
    public event Action<HeroListChangedEventArgs> HeroListChanged;
    
    // 英雄列表（只读）
    public IReadOnlyList<HeroModel> Heroes => _heroes.AsReadOnly();
    
    // 英雄数量
    public int HeroCount => _heroes.Count;
    
    // 已解锁英雄数量
    public int UnlockedHeroCount => _heroes.Where(h => h.IsUnlocked).Count();
    
    // 添加英雄
    public void AddHero(HeroModel hero)
    {
        if (_heroDict.ContainsKey(hero.HeroId))
        {
            Debug.LogWarning($"英雄 {hero.HeroName} (ID: {hero.HeroId}) 已存在！");
            return;
        }
        
        _heroes.Add(hero);
        _heroDict[hero.HeroId] = hero;
        
        // 监听英雄属性变化
        hero.AddPropertyChangedListener(OnHeroPropertyChanged);
        
        // 触发列表变化事件
        OnHeroListChanged(HeroListChangedEventArgs.ChangeType.Added, hero, _heroes.Count - 1);
        
        Debug.Log($"添加英雄: {hero.HeroName} (ID: {hero.HeroId})");
    }
    
    // 删除英雄
    public bool RemoveHero(int heroId)
    {
        if (!_heroDict.TryGetValue(heroId, out var hero))
        {
            Debug.LogWarning($"英雄 ID {heroId} 不存在！");
            return false;
        }
        
        int index = _heroes.IndexOf(hero);
        _heroes.RemoveAt(index);
        _heroDict.Remove(heroId);
        
        // 移除英雄属性变化监听
        hero.RemovePropertyChangedListener(OnHeroPropertyChanged);
        
        // 触发列表变化事件
        OnHeroListChanged(HeroListChangedEventArgs.ChangeType.Removed, hero, index);
        
        Debug.Log($"删除英雄: {hero.HeroName} (ID: {heroId})");
        return true;
    }
    
    // 获取英雄
    public HeroModel GetHero(int heroId)
    {
        _heroDict.TryGetValue(heroId, out var hero);
        return hero;
    }
    
    // 获取英雄（通过索引）
    public HeroModel GetHeroByIndex(int index)
    {
        if (index >= 0 && index < _heroes.Count)
            return _heroes[index];
        return null;
    }
    
    // 检查英雄是否存在
    public bool HasHero(int heroId)
    {
        return _heroDict.ContainsKey(heroId);
    }
    
    // 获取所有已解锁的英雄
    public List<HeroModel> GetUnlockedHeroes()
    {
        return _heroes.Where(h => h.IsUnlocked).ToList();
    }
    
    // 获取指定星级的英雄
    public List<HeroModel> GetHeroesByStar(int star)
    {
        return _heroes.Where(h => h.Star == star).ToList();
    }
    
    // 英雄属性变化处理
    private void OnHeroPropertyChanged(ModelPropertyChangedEventArgs args)
    {
        var hero = args.Target as HeroModel;
        if (hero != null)
        {
            // 触发列表更新事件
            OnHeroListChanged(HeroListChangedEventArgs.ChangeType.Updated, hero);
        }
    }
    
    // 触发英雄列表变化事件
    private void OnHeroListChanged(HeroListChangedEventArgs.ChangeType type, HeroModel hero, int index = -1)
    {
        HeroListChanged?.Invoke(new HeroListChangedEventArgs(type, hero, index));
    }
    
    // 添加英雄列表变化监听器
    public void AddHeroListChangedListener(Action<HeroListChangedEventArgs> listener)
    {
        HeroListChanged += listener;
    }
    
    // 移除英雄列表变化监听器
    public void RemoveHeroListChangedListener(Action<HeroListChangedEventArgs> listener)
    {
        HeroListChanged -= listener;
    }
    
    // 清除所有监听器
    public void ClearHeroListChangedListeners()
    {
        HeroListChanged = null;
    }
    
    // 批量添加英雄（用于初始化）
    public void AddHeroes(List<HeroModel> heroes)
    {
        foreach (var hero in heroes)
        {
            AddHero(hero);
        }
    }
    
    // 清空所有英雄
    public void ClearAllHeroes()
    {
        foreach (var hero in _heroes)
        {
            hero.RemovePropertyChangedListener(OnHeroPropertyChanged);
        }
        
        _heroes.Clear();
        _heroDict.Clear();
        
        Debug.Log("清空所有英雄");
    }
}

// 英雄系统测试类
public class HeroSystemTest : MonoBehaviour
{
    private HeroListModel _heroListModel;
    
    void Start()
    {
        Debug.Log("=== 英雄系统测试开始 ===");
        
        // 获取英雄列表模型
        _heroListModel = ModelManager.GetModel<HeroListModel>();
        
        // 添加监听器
        _heroListModel.AddHeroListChangedListener(OnHeroListChanged);
        
        // 开始测试
        StartCoroutine(RunHeroSystemTests());
    }
    
    System.Collections.IEnumerator RunHeroSystemTests()
    {
        yield return new WaitForSeconds(1f);
        
        Debug.Log("1. 创建并添加英雄");
        var hero1 = new HeroModel(1, "亚瑟");
        var hero2 = new HeroModel(2, "妲己");
        var hero3 = new HeroModel(3, "孙悟空");
        
        _heroListModel.AddHero(hero1);
        _heroListModel.AddHero(hero2);
        _heroListModel.AddHero(hero3);
        
        yield return new WaitForSeconds(1f);
        
        Debug.Log("2. 测试英雄属性变化");
        hero1.LevelUp();
        hero2.StarUp();
        hero3.Unlock();
        
        yield return new WaitForSeconds(1f);
        
        Debug.Log("3. 测试获取英雄");
        var foundHero = _heroListModel.GetHero(2);
        if (foundHero != null)
        {
            Debug.Log($"找到英雄: {foundHero.HeroName}, 星级: {foundHero.Star}");
        }
        
        yield return new WaitForSeconds(1f);
        
        Debug.Log("4. 测试删除英雄");
        _heroListModel.RemoveHero(2);
        
        yield return new WaitForSeconds(1f);
        
        Debug.Log("5. 测试获取已解锁英雄");
        var unlockedHeroes = _heroListModel.GetUnlockedHeroes();
        Debug.Log($"已解锁英雄数量: {unlockedHeroes.Count}");
        
        yield return new WaitForSeconds(1f);
        
        Debug.Log("6. 测试重复添加英雄");
        _heroListModel.AddHero(hero1); // 应该不会添加，因为已存在
        
        yield return new WaitForSeconds(1f);
        
        Debug.Log("7. 测试删除不存在的英雄");
        _heroListModel.RemoveHero(999); // 应该返回false
        
        yield return new WaitForSeconds(1f);
        
        Debug.Log("=== 英雄系统测试完成 ===");
    }
    
    private void OnHeroListChanged(HeroListChangedEventArgs args)
    {
        switch (args.Type)
        {
            case HeroListChangedEventArgs.ChangeType.Added:
                Debug.Log($"[英雄列表] 添加英雄: {args.Hero.HeroName} (ID: {args.Hero.HeroId}) 在位置 {args.Index}");
                break;
            case HeroListChangedEventArgs.ChangeType.Removed:
                Debug.Log($"[英雄列表] 删除英雄: {args.Hero.HeroName} (ID: {args.Hero.HeroId}) 从位置 {args.Index}");
                break;
            case HeroListChangedEventArgs.ChangeType.Updated:
                Debug.Log($"[英雄列表] 英雄属性更新: {args.Hero.HeroName} (ID: {args.Hero.HeroId})");
                break;
        }
    }
    
    void OnDestroy()
    {
        // 清理监听器
        if (_heroListModel != null)
        {
            _heroListModel.RemoveHeroListChangedListener(OnHeroListChanged);
        }
    }
} 